#ifndef DEV_MEASURE_H
#define DEV_MEASURE_H

#include <QThread>
#include <vector>
#include <queue>
#include <mutex>
#include <memory>
#include <map>
#include <QSerialPort>
#include <QSerialPortInfo>
#include "frm_struct_def.h"
#include "common_typedef.h"
#include "cioMst.h"

using byteStream = std::vector<uint8_t>; // 字节流
namespace KzDeviceConst {
constexpr size_t KZDEVICE_MST_PERIOD = 1;
}

class KzDevice : public QThread
{
    Q_OBJECT
public:
    enum DevState : uint64_t {
        COM_FAIL,
        DEV_OFFLINE,
        DEV_RDY,
        DEV_WAITACK,
        DEV_ERROR,
    };
    ERRCODE Initialize(const std::string& devType);
    // 内联方法
    MstStatisticsHandle GetStatic() { return m_cio->GetStatic(); }
    bool IsPortOpen() const { return m_port->isOpen(); }
    DevState GetState() const { return m_devState; }
    void ForceStop(bool isStop) { m_isForceStop = isStop; }
    bool IsParaUpdated(); // 读清

signals:

public slots:
    void SlotPortLink(QString portName, LINK_CMD_TYPE cmd);
    void SlotRequestDump();
private slots:
    void SlotPortError(QSerialPort::SerialPortError errInfo);

private:
    std::unique_ptr<cioMst> m_cio { nullptr };
    std::mutex m_rxBufferLocker;
    void run() override;
    void RxProc(std::queue<MstCioObj>& rxEvnet);
    void TxProc();
    void EventProc(std::queue<MstCioObj>& rxEvnet);
    ERRCODE PingDevice();

private: // 数据缓存
    std::mutex m_rxEventMtx; // 接收队列事件锁
    std::queue<MstCioObj> m_rxEvent; // 接收Buffer由协议维护，解码为事件转发给本对象
    std::mutex m_txBufferMtx; // 发送缓冲区锁
    byteStream m_txBuffer; // 发送Buffer由对象自己维护，协议只完成打包

private:
    DevState m_devState { COM_FAIL };
    std::string m_devType;
    bool m_isForceStop { false };
    uint32_t m_devID[3] {0};
protected: // 回调函数和任务注册列表
    std::map<pkgType, std::function<int(const uint8_t *, size_t)>> m_exeTable = {
    {DEV_PONG,          [this](const uint8_t *data, size_t len) { return Pong(data, len);           }},
    {MST_DISCONNECT,    [this](const uint8_t *data, size_t len) { return MstDisconnect(data, len);  }},
    {MST_CONNECT,       [this](const uint8_t *data, size_t len) { return MstConnect(data, len);     }},
    {MST_READDUMP,      [this](const uint8_t *data, size_t len) { return MstRequestDump(data, len); }},
    {DEV_DUMP,          [this](const uint8_t *data, size_t len) { return MstEchoDump(data, len);    }},
    };
    bool m_isUpdated { false }; // dump刷新信息
    // 子类添加回调函数的接口
    virtual void ConfigCmdHandle() = 0;
    // 响应设备的Pong帧
    int Pong(const uint8_t* data, size_t len);
    // 设备连接/断开帧
    int MstConnect(const uint8_t* data, size_t len);
    int MstDisconnect(const uint8_t* data, size_t len);
    int MstRequestDump(const uint8_t* data, size_t len);
    virtual int MstEchoDump(const uint8_t* data, size_t len);
    void TxPkg(pkgType type, const void* data = nullptr, size_t len = 0);
    void AddTask(pkgType type, const void* data, size_t len);
    void AddTask(const MstCioObj& newTask);
    void AddTask(pkgType type);
/* 数据通信端口相关方法 */
private:
    std::unique_ptr<QSerialPort> m_port;
    byteStream RecvPortData();
    int m_timeout { 0 };
    void UpdateRecvTimeout();
    void UpdateDevState();
};

#endif // DEV_MEASURE_H
